import { useState, useCallback, useEffect, useRef, useMemo } from "react";
import { View, Text, TouchableOpacity, Alert, Pressable, ActivityIndicator } from "react-native";
import { FlashList } from "@shopify/flash-list";
import DateTimePickerModal from "react-native-modal-datetime-picker";
import dayjs from "dayjs";
// @ts-ignore
import DialogAndroid from "react-native-dialogs";

import fso from "@/utils/FileOperate/operate";
import { getPermissions } from "@/utils";
import { Module } from "@/utils/nativeModules";

import CustomIcon from "@/components/CustomIcon";
import globalMethods from "@/GlobalMethodProvider";

import styles from "./styles";

import type { StateType } from "./type";
import config from "@/config";

/** 日志查询 */
const Logger = () => {
  const [state, _setState] = useState<StateType>({
    currentDate: new Date(),
    fileList: [],
    currentIdx: 0,
    isDatePickerVisible: false,
    loading: true
  });

  /** 当前读取的文件地址 */
  const fileUrl = useMemo(() => {
    return fso.logDir + dayjs(state.currentDate).format("/YYYY_MM_DD.log");
  }, [state.currentDate]);

  // 通用更新状态单个
  const setState = useCallback((field: keyof typeof state, val: any) => {
    _setState(_state => {
      return { ..._state, [field]: val };
    });
  }, []);

  // 通用更新状态(对象)
  const setObjState = useCallback((obj: Partial<typeof state>) => {
    _setState(_state => {
      return { ..._state, ...obj };
    });
  }, []);

  const FlashListRef = useRef<FlashList<any>>(null);

  // 获取下一个索引位置
  const getNextIndex = (index: number) => {
    let ret = state.currentIdx;
    if (FlashListRef.current) {
      const nextIdx = state.currentIdx + index;
      if (nextIdx < 0) {
        ret = 0;
      } else if (nextIdx > state.fileList.length - 1) {
        ret = state.fileList.length - 1;
      } else {
        ret = nextIdx;
      }
    }
    console.log("state: ", state);

    return ret;
  };

  // 滚动到指定的位置
  const scrollToIndex = (n: number) => {
    const idx = getNextIndex(n);
    if (FlashListRef.current) {
      FlashListRef.current.scrollToIndex({
        index: idx,
        animated: true
      });
      setState("currentIdx", idx);
    }
  };

  /** 读取文件内容 */
  const readFileContent = useCallback(
    async (url: string) => {
      try {
        const isExists = await fso.exists(url);
        if (isExists) {
          console.log(`读取 ${url} 文件`);
          const content = await fso.readFile(url);
          const list = content
            .split("\n")
            .filter(e => e.trim())
            .map((e, i) => ({ id: i.toString(), value: e }));
          setState("fileList", list);
        } else {
          setState("fileList", [{ id: "0", value: `该文件地址 ${url} 不存在` }]);
        }
      } catch (err) {
        console.log("err: ", err);
        setState("fileList", [{ id: "0", value: `文件读取失败: ${err}` }]);
      }
    },
    [setState]
  );

  /** 打开日志文件内容 */
  const openLog = async () => {
    try {
      const isExists = await fso.exists(fileUrl);
      if (isExists) {
        Alert.alert("提示", "确定要查看日志文件吗?", [
          { text: "取消", style: "cancel" },
          {
            text: "确定",
            onPress: () => {
              Module.actionViewIntent(fileUrl, "text");
            }
          }
        ]);
      } else {
        globalMethods.$showMessage({
          type: "toast",
          message: "文件不存在"
        });
      }
    } catch (err) {
      console.log("err: ", err);
      globalMethods.$showMessage({
        type: "toast",
        message: "文件查看失败"
      });
    }
  };

  /** 上传文件 */
  const uploadFile = async () => {
    try {
      const isExists = await fso.exists(fileUrl);
      if (isExists) {
        const { action, text } = await DialogAndroid.prompt("上传日志", "输入上传日志的接口地址", {
          defaultValue: `${config.serveUrl.localhostServe}/uploadFile`,
          cancelable: false
        });

        if (action === DialogAndroid.actionPositive) {
          console.log("上传文件: ", fileUrl);

          DialogAndroid.showProgress("文件上传中, 请稍等...", {
            style: DialogAndroid.circular
          });

          const res = await fso
            .uploadFile({
              url: text,
              method: "POST",
              fileName: dayjs(state.currentDate).format("YYYY_MM_DD.log"),
              filePath: fileUrl,
              formDataKey: "file"
            })
            .finally(() => {
              DialogAndroid.dismiss();
            });
          console.log("res: ", res);
          globalMethods.$showMessage({
            type: "toast",
            message: "上传成功"
          });
        }
      } else {
        globalMethods.$showMessage({
          type: "toast",
          message: "文件不存在"
        });
      }
    } catch (err) {
      console.log("err: ", err);
      globalMethods.$showMessage({
        type: "toast",
        message: "文件上传失败"
      });
    }
  };

  /** Loaidng 组件 */
  const LoadingComp = <ActivityIndicator style={styles.loading} animating={state.loading} size={28} color="white" />;

  /** 内容组件 */
  const ContentComp = (
    <FlashList
      ref={FlashListRef}
      data={state.fileList}
      keyExtractor={item => item.id}
      estimatedItemSize={200}
      renderItem={({ item }) => {
        return (
          <Pressable key={item.id}>
            <Text style={styles.text}>{item.value}</Text>
          </Pressable>
        );
      }}
    />
  );

  useEffect(() => {
    // 获取文件读写权限
    if (fso.getExternalFilePermission) {
      getPermissions("android.permission.READ_EXTERNAL_STORAGE", "文件读取权限");
      getPermissions("android.permission.WRITE_EXTERNAL_STORAGE", "文件写入权限");
    }
  }, []);

  useEffect(() => {
    readFileContent(fileUrl);
  }, [readFileContent, setState, fileUrl]);

  return (
    <View style={styles.container}>
      <View style={styles.contentContainer}>
        <View>
          <View style={styles.contentHeader}>
            <Text>
              日志文件地址:
              <Text style={styles.contentTitle}>{fso.formatPath(fileUrl)}</Text>
            </Text>

            <TouchableOpacity style={styles.iconContainer} onPress={() => readFileContent(fileUrl)}>
              <CustomIcon name="icon-Sync" size={20} />
            </TouchableOpacity>

            <TouchableOpacity
              style={styles.iconContainer}
              onPress={() => {
                setState("isDatePickerVisible", true);
              }}
            >
              <CustomIcon name="icon-tubiao_riqi" size={20} />

              <DateTimePickerModal
                isVisible={state.isDatePickerVisible}
                date={state.currentDate}
                mode="date"
                onConfirm={date => {
                  setObjState({
                    isDatePickerVisible: false,
                    currentDate: date
                  });
                }}
                onCancel={() => setState("isDatePickerVisible", false)}
              />
            </TouchableOpacity>

            <TouchableOpacity style={styles.iconContainer} onPress={openLog}>
              <CustomIcon name="icon-wendang" size={20} />
            </TouchableOpacity>

            <TouchableOpacity style={styles.iconContainer} onPress={uploadFile}>
              <CustomIcon name="icon-shangchuan" size={20} />
            </TouchableOpacity>
          </View>
          <View style={styles.division} />
        </View>

        {state.fileList.length ? ContentComp : LoadingComp}
      </View>

      {/* 右边按钮操作部分 */}
      {state.fileList.length !== 0 && (
        <View style={styles.btnContainer}>
          <TouchableOpacity onPress={() => scrollToIndex(-state.fileList.length)}>
            <CustomIcon name="icon-xiangshang3" size={40} />
          </TouchableOpacity>
          <TouchableOpacity onPress={() => scrollToIndex(state.fileList.length)}>
            <CustomIcon name="icon-xiangshang3" size={40} style={{ transform: [{ rotate: "180deg" }] }} />
          </TouchableOpacity>
        </View>
      )}
    </View>
  );
};

export default Logger;
